#include "client.h"

char own_name[20];

void Main_Interface ()
{
	system ("clear");
	printf ("\t*****************************************\n");
	printf ("\t~                                       ~\n");
	printf ("\t~          Welcome To Chatroom          ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~           1 >>>>>>>>>  注册           ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~           2 >>>>>>>>>  登录           ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~           3 >>>>>>>>>  退出           ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~                      作者：咖啡不解困  ~\n");
	printf ("\t*****************************************\n");
	printf ("                                           \n");
	printf ("                                           \n");
	printf ("\t请选择：");
} 

void Common_User_Interface ()
{    
	system ("clear");
	printf ("\t*****************************************\n");
	printf ("\t~                                       ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~       1 >>>>>>>>>  私聊               ~\n");
	printf ("\t~       2 >>>>>>>>>  群聊               ~\n");
	printf ("\t~       3 >>>>>>>>>  查看在线用户        ~\n");
	printf ("\t~       4 >>>>>>>>>  查看用户信息        ~\n");
	printf ("\t~       5 >>>>>>>>>  查看聊天记录        ~\n");
	printf ("\t~       6 >>>>>>>>>  退出               ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~                                       ~\n");
	printf ("\t~                           作者：薛嵩   ~\n");
	printf ("\t*****************************************\n");
	printf ("                                           \n");
	printf ("                                           \n");
	printf ("\t请选择：");
	
}
//填写注册内容
void Register(struct user *userInfo)  
{
	userInfo->cmd = REGISTER;
	printf ("\t请输入您的用户名: ");
	scanf ("%s", userInfo->name);
	while(1)
	{
		printf ("\t请输入您的密码: ");
		scanf ("%s", userInfo->password);
		printf ("\t请确认您的密码: ");
		scanf ("%s", userInfo->npassword);
		if (strcmp(userInfo->password, userInfo->npassword) != 0)
		{
			printf ("\t密码设置错误，请重新输入！\n");
			continue;
		}
		break;
	}
}

//登录
void Login(struct user *userInfo)  
{
	userInfo->cmd = LOG_IN;
	printf ("\t用户名: ");
	scanf ("%s", userInfo->name);
	printf ("\t密码: ");
	scanf ("%s", userInfo->password);
}

//私聊
void Chat_one(struct user *userInfo, struct Info_buffer *Ibuf)  
{
	userInfo->cmd = CHAT_ONE; 
	strcpy(userInfo->name, Ibuf->own_name);
	printf ("\t私聊对象: ");
	scanf ("%s", userInfo->toname);
	strcpy(Ibuf->to_name, userInfo->toname);
	
}

//群聊
void Chat_all(struct user *userInfo, struct Info_buffer *Ibuf)  
{
	userInfo->cmd = CHAT_ALL; 
	strcpy(userInfo->name, Ibuf->own_name);
}

//写消息
void Write_msg (struct user *userInfo, struct Info_buffer *Ibuf)
{
	printf ("%s：", Ibuf->own_name);
	scanf ("%s", userInfo->msg);
	printf ("\n");
}

//退出登录
void Quit_login(struct user *userInfo, struct Info_buffer *Ibuf)  
{
	userInfo->cmd = QUIT_LOGIN; 
	strcpy(userInfo->name, Ibuf->own_name);
}

//查看在线用户
void print_OLuser(struct user *userInfo)  
{
	userInfo->cmd = ONLINE_USER; 
}

void* write_to_server(void *arg)
{
	int sfd = (int)arg;
	struct user userInfo; 
	struct Info_buffer Ibuf;
	
	Main_Interface ();
	
	int cho;
	while (1)
	{
		char Function[3]; 
		while (1)
		{
			scanf ("%s", Function);
			if (strlen(Function) != 1)
			{
				printf ("命令错误！请重新输入：");
				continue;
			}
			break;
		}
		switch (Function[0])
		{
			case '1'://注册
			{
				while (1)
				{
					system ("clear");
					memset(Function, 0, sizeof(Function));
					memset(userInfo.name, 0, sizeof(userInfo.name));
					memset(userInfo.password, 0, sizeof(userInfo.password));
					memset(userInfo.npassword, 0, sizeof(userInfo.npassword));
					int temp = 1;	
					Register(&userInfo);
					
					printf ("\t注册中.....\n");	
					
					int writeSize = write(sfd, &userInfo, sizeof(userInfo));
					if (writeSize == -1)
					{
						perror("write");
						return;
					}
					
					sleep(1);
					if (temp_result == REGISTER_FAIL)
					{
						printf ("\ttemp_result = %d\n", temp_result);
						temp_result = 0;
						printf ("\t注册失败！\n");
						Main_Interface ();
						break;
					}
					else if (temp_result = REGISTER_SUCCESS)
					{
						//printf ("\ttemp_result = %d\n", temp_result);
						temp_result = 0;
						printf ("\t返回主菜单请输入1，继续注册输入2：");
						while (1)
						{
							scanf ("%d",&cho);
							if (cho == 1)
							{
								temp = 0;
								Main_Interface ();
								break;
							}
							 
							else if (cho == 2)
							{
								temp = 1;
								break;
							}
							
							else
							{
								printf ("\t命令错误！请重新输入：");
								continue;
							} 
						}
					}
					
					if (temp == 1)
					{
						continue;
					}
					
					break;
				}
				break;
			}
			
			case '2'://登录
			{
				system ("clear");
				memset(Function, 0, sizeof(Function));
				
				while (1)
				{
					memset(userInfo.name, 0, sizeof(userInfo.name));
					memset(userInfo.password, 0, sizeof(userInfo.password));
					Login(&userInfo);
					strcpy(Ibuf.own_name, userInfo.name);
					int writeSize = write(sfd, &userInfo, sizeof(userInfo));
					if (writeSize == -1)
					{
						perror("write");
						return;
					}
		
					sleep(1);
					if (temp_result == NAME_ERROR || temp_result == PASSWORD_ERROR 
							|| temp_result == NOT_REGISTER || temp_result == LOGIN_REPEAT)
					{
						//printf ("\ttemp_result = %d\n", temp_result);
						temp_result = 0;
						continue;
					}
					else if (temp_result == LOGIN_SUCCESS )
					{
						//printf ("\ttemp_result = %d\n", temp_result);
						temp_result = 0;
						break;
					}
				}
				
				system("clear");
				Common_User_Interface (); //跳转到普通用户界面
				while (1)
				{
					char fu[3]; 
					while (1)
					{
						scanf ("%s", fu);
						if (strlen(fu) != 1)
						{
							printf ("命令错误！请重新输入：");
							continue;
						}
						break;
					}
					switch (fu[0])
					{
						case '1': //私聊
						{
							system ("clear");
							
							memset(userInfo.name, 0, sizeof(userInfo.name));
							memset(userInfo.toname, 0, sizeof(userInfo.toname));
							memset(userInfo.msg, 0, sizeof(userInfo.msg));
							
							//建一个文本文件保存用户聊天记录
							char ch1[10] = {0};
							char ch2[10] = ".txt";
							char ch3[20] = {0};
							
							strcpy (ch1, Ibuf.own_name);
							strcpy (ch3, Ibuf.own_name);
							strcat (ch3, ch2);
							
							int fd_chat = open (ch3, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
							if (-1 == fd_chat)
							{
								perror("open TXT");
								return;
							}
							
							close(fd_chat);
							
							Chat_one(&userInfo, &Ibuf);
							//printf ("\t你给%s发了一条消息：%s\n", userInfo.toname, userInfo.msg);
							system ("clear");
							printf ("私聊对象：%s\n", Ibuf.to_name);
							
							char ch[5] = "end";
							int ch4;
							while (1)
							{
								setbuf(stdin, NULL); //清空键盘缓冲区
								ch4 = getchar();
								if (ch4 == '\n')
								{
									Write_msg (&userInfo, &Ibuf);
									
									if (strcmp (userInfo.msg, ch) == 0)
									{
										break;
									}
									
									int writeSize = write(sfd, &userInfo, sizeof(userInfo));
									if (writeSize == -1)
									{
										perror("write");
										return;
									}
									
									sleep(1);
									if (temp_result == NO_GOAL || temp_result == LOGIN_NULL)
									{
										break;
									}
									
									//保存聊天记录
									FILE *file_in = fopen(ch3, "a+");
									if (file_in == NULL)
									{
										perror("fopen TXT");
										return 0;
									}

									fprintf (file_in, "%s", ch1);
									fprintf (file_in, "给");
									fprintf (file_in, "%s", userInfo.toname);
									fprintf (file_in, "发了一条消息：");
									fprintf (file_in, "%s", userInfo.msg);
									fprintf (file_in, "\r\n");
						
									fclose (file_in);
									
									sleep(1);
								}
								
							}

							Common_User_Interface ();
							break;
						}
						
						case '2'://群聊
						{
							system ("clear");
							
							memset(userInfo.name, 0, sizeof(userInfo.name));
							memset(userInfo.toname, 0, sizeof(userInfo.toname));
							
							//建一个文本文件保存用户聊天记录
							char ch1[10] = {0};
							char ch2[10] = ".txt";
							char ch3[20] = {0};
							
							strcpy (ch1, Ibuf.own_name);
							strcpy (ch3, Ibuf.own_name);
							strcat (ch3, ch2);
							
							int fd_chat = open (ch3, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
							if (-1 == fd_chat)
							{
								perror("open TXT");
								return;
							}
							
							close(fd_chat);
							
							Chat_all(&userInfo, &Ibuf);
							//printf ("\t你给所有人发了一条消息：%s\n", userInfo.msg);
							
							system ("clear");
							printf ("群聊\n");
							
							char ch[5] = "end";
							int ch4;
							while (1)
							{
								setbuf(stdin, NULL); //清空键盘缓冲区
								ch4 = getchar();
								if (ch4 == '\n')
								{
									Write_msg (&userInfo, &Ibuf);
					
									if (strcmp (userInfo.msg, ch) == 0)
									{
										break;
									}
									int writeSize = write(sfd, &userInfo, sizeof(userInfo));
									if (writeSize == -1)
									{
										perror("write");
										return;
									}
									
									sleep(1);
									if (temp_result == NO_GOAL || temp_result == LOGIN_NULL)
									{
										break;
									}
									
									//保存聊天记录
									FILE *file_in = fopen(ch3, "a+");
									if (file_in == NULL)
									{
										perror("fopen TXT");
										return 0;
									}

									fprintf (file_in, "%s", ch1);
									fprintf (file_in, "给");
									fprintf (file_in, "%s", userInfo.toname);
									fprintf (file_in, "发了一条消息：");
									fprintf (file_in, "%s", userInfo.msg);
									fprintf (file_in, "\r\n");
						
									fclose (file_in);
									
									sleep(1);
								}
								
							}
							Common_User_Interface ();
							break;
						}
						
						case '3':// 查看在线用户
						{
							print_OLuser(&userInfo);
							
							int writeSize = write(sfd, &userInfo, sizeof(userInfo));
							if (writeSize == -1)
							{
								perror("write");
								return;
							}
							
							sleep(1);
							while (1)
							{
								if (temp_result == SEND_END)
								{
									printf ("\n");
									int a;
									printf ("按任意键返回...");
									setbuf(stdin, NULL); //清空键盘缓冲区
									a = getchar();
									Common_User_Interface ();
									break;
								}
								
								else 
								{
									continue;
								}
								
							}
						
							break;
						}
						
						case '4':
						{
							printf ("暂无此功能！\n");
							sleep(1);
							break;
						}
						
						case '5'://查看聊天记录
						{
							system ("clear");
							char ch1[30] = {0};
							char ch2[10] = ".txt";
							int a;
							
							strcpy (ch1, Ibuf.own_name);
							strcat (ch1, ch2);
							
							FILE *file_in = fopen(ch1, "r");   //以只读方式打开文件         
							if (file_in == NULL)
							{
								perror("fopen TXT");
								printf ("没有该用户的聊天记录！\n");
								continue;
							}
							
							printf ("\n");
							
							char ch;
							while (1)
							{
								ch = fgetc(file_in);
								if (ch == EOF)
								{
									break;
								}
								printf ("%c", ch);
							}
							
							printf ("\n");
							printf ("按任意键返回...");
							setbuf(stdin, NULL); //清空键盘缓冲区
							a = getchar();
							Common_User_Interface ();
							
							break;
						}
						
						case '6': //退出登录
						{
							Quit_login(&userInfo, &Ibuf);
							
							int writeSize = write(sfd, &userInfo, sizeof(userInfo));
							if (writeSize == -1)
							{
								perror("write");
								return;
							}
							
							sleep(1);
							if (temp_result == QUIT_SUCCESS)
							{
								Main_Interface ();
								break;
							}
		
							break;
						}
						
						default://命令错误
						{
							printf ("\t命令错误！请重新输入：");
							break;
						} 
					}
					
					if (fu[0] != '6')
					{
						continue;
					}
					break;
				}
				
				break;
			}
			
			case '3':
			{
				system ("clear");
				shutdown(sfd,2);
				exit(0);
				break;
			}
			
			
			default://命令错误
			{
				printf ("命令错误！请重新输入：");
				break;
			} 
			
		}
		/* printf ("\tcmd = %d\n",userInfo.cmd);
		int writeSize = write(sfd, &userInfo, sizeof(userInfo));
		if (writeSize == -1)
		{
			perror("write");
			return;
		} */
	}
}

void* read_from_server(void *arg) 
{
	int sfd = (int)arg;
	struct user userInfo;
	while (1)
	{
		memset(userInfo.msg, 0, sizeof(userInfo.msg));
		
		int readSize = read(sfd, &userInfo, sizeof(userInfo));
		if (readSize == -1)
		{
			perror("read");
			return;
		}
		
		switch(userInfo.result)
		{
			case REGISTER_SUCCESS:
			{
				printf ("\t注册成功！\n");
				temp_result = REGISTER_SUCCESS;
				break;
			}
			
			case REGISTER_REPEAT:
			{
				printf ("\t该用户名已被注册！\n");
				break ;
			}
			
			case  REGISTER_FAIL:
			{
				printf ("\t注册失败！\n");
				temp_result = REGISTER_FAIL;
				//printf ("\n%s send msg to you: %s\n", userInfo.name, userInfo.msg);
				break;
			}
			
			case NOT_REGISTER:
			{
				printf ("\t该用户未注册！\n");
				break;
			}
			
			case LOGIN_FAIL:
			{
				printf ("\t登录失败！\n");
				temp_result = LOGIN_FAIL;
				break;
			}
			
			case LOGIN_SUCCESS:
			{
				printf ("\t登录成功！\n");
				temp_result = LOGIN_SUCCESS;
				break;
			}
			
			case PASSWORD_ERROR:
			{
				printf ("\t密码错误！\n");
				temp_result = PASSWORD_ERROR;
				break;
			}
			
			case NAME_ERROR:
			{
				printf ("\t用户名错误！\n");
				temp_result = NAME_ERROR;
				break;
			}
			
			case LOGIN_REPEAT:
			{
				printf ("\t该用户已登录，不能重复登录！\n");
				break;
			}
			
			case LOGIN_NULL:
			{
				printf ("\t该用户未登录！\n");
				break;
			}
			
			case QUIT_SUCCESS:
			{
				temp_result = QUIT_SUCCESS;
				printf ("\t下线成功！\n");
				break;
			}
			
			case FIND_GOAL:
			{
				//printf ("\t%s给你发了一条消息：%s\n", userInfo.name, userInfo.msg);
				printf ("\t\t\t\t%15s :%s\n", userInfo.msg, userInfo.name);
				
				//保存聊天记录
				char ch1[10] = {0};
				char ch2[10] = ".txt";
				char ch3[20] = {0};
				
				strcpy (ch1, userInfo.name);
				strcpy (ch3, own_name);
				strcat (ch3, ch2);
							
				FILE *file_in = fopen(ch3, "a+");
				if (file_in == NULL)
				{
					perror("fopen TXT");
					return 0;
				}

				fprintf (file_in, "%s", ch1);
				fprintf (file_in, "给");
				fprintf (file_in, "%s", own_name);
				fprintf (file_in, "发了一条消息：");
				fprintf (file_in, "%s", userInfo.msg);
				fprintf (file_in, "\r\n");
	
				fclose (file_in);
				
				memset(userInfo.name, 0, sizeof(userInfo.name));
				memset(userInfo.msg, 0, sizeof(userInfo.msg));
				break;
			}
			
			case NO_GOAL:
			{
				printf ("\t未找到发送对象！\n");
				break;
			}
			
			case SEND_SUCCESS:
			{
				printf ("\t消息发送成功！\n");
				break;
			}
			
			case SEND_FAIL:
			{
				printf ("\t消息发送失败！\n");
				break;
			}
			
			case SEND_END:
			{
				temp_result = SEND_END;
				break;
			}
			
			case OLUSER_SUCCESS://在线用户
			{
				printf ("\t在线用户：");
				printf ("%s\n", userInfo.name);
				memset(userInfo.name, 0, sizeof(userInfo.name));
				break;
			}
			
			case KICK_USER:
			{
				printf ("\t你已被踢出聊天室！\n");
				break;
			}
			
			case BAN_USER:
			{
				printf ("\t你已被禁言！\n");
				break;
			}
		}
	}
	
}

int main(int argc, char *argv[])
{
	int server_sockfd;
	int ret;
	struct sockaddr_in client_addr; 
	struct user userInfo;
	
	if (argc != 2)
	{
		printf ("Usage:./client IP_ADDRESS\n");
		return -1;
	}
	
	/* //初始化信号量
	int result = sem_init(&bin_sem, 0, 0);
	if(result != 0)  
    { 
        printf("sem init error!\n");  
        exit(EXIT_FAILURE);  
    }   */
	
	// 创建监听套接字
	server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (server_sockfd == -1)
	{
		perror("create socket error");
		return -1;
	}
	
	// 初始化服务器地址结构
	bzero(&client_addr, sizeof(client_addr));     // 将地址结构变量清零
	client_addr.sin_family = AF_INET;             // 选择IPV4地址
	inet_aton(argv[1], &client_addr.sin_addr);    // 填写服务器地址
	client_addr.sin_port = htons(SERV_PORT);      // 填写服务器端口

	// 连接服务器
	ret = connect(server_sockfd, (struct sockaddr *)&client_addr,  sizeof (client_addr));
	if (ret != 0)
	{
		perror("connect error");
		return -1;
	} 
	
	
	pthread_t tid1;
	pthread_t tid2;
	
	//  创建写线程
	ret = pthread_create(&tid1, NULL, write_to_server, (void *)server_sockfd);
	if (ret != 0)
	{
		printf ("create pthread error!\n");
		return -1;
	}
	pthread_detach(tid1); // 线程分离
	
	// 创建读线程
	ret = pthread_create(&tid2, NULL, read_from_server, (void *)server_sockfd);
	if (ret != 0)
	{
		printf ("create pthread error!\n");
		return -1;
	}
	pthread_detach(tid2);  // 线程分离
	
	while (1);
	close(server_sockfd);

	return 0;
}
